package com.feeyo.prophet.actions.flight;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.feeyo.llm.agent.engine.*;
import com.feeyo.llm.util.JsonUtil;
import com.feeyo.prophet.plugins.FlightScheduleActionUtils;
import com.feeyo.prophet.pojo.action.flight.AirlineRank;
import com.feeyo.prophet.pojo.action.functioncall.flight.AirlineRankProperties;
import com.feeyo.prophet.pojo.action.functioncall.FunctionCall;
import com.feeyo.prophet.pojo.action.functioncall.ItemsBean;
import com.feeyo.prophet.pojo.action.functioncall.flight.common.BasicTypeDefaultList;
import com.feeyo.prophet.pojo.action.rank.AirlineRankResp;
import com.feeyo.prophet.config.ParametersSingletonManager;
import com.feeyo.prophet.plugins.AnswerUtils;
import com.feeyo.prophet.plugins.ConstantUtils;
import com.feeyo.prophet.plugins.DbSearchActionUtils;
import com.google.common.collect.Lists;
import io.micrometer.common.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.http.HttpStatus;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 查询航司排名
 *
 * @author lihu
 */
@Slf4j
public class AirlineRankAction implements Action {
    private final String host;
    private final Integer port;

    public AirlineRankAction(String host, Integer port) {
        this.host = host;
        this.port = port;
    }

    @Override
    public String human() {
        return "查询航司排名";
    }

    @Override
    public String name() {
        return "AirlineRankAction";
    }

    @Override
    public String eg() {
        return """
                Question: 2024年1月份东方航空公司航班量排名多少？
                Thought: 我应该使用AirlineRankAction查找指定航司航班量排名
                Action: AirlineRankAction
                Action Input: {"startDate":"2024-01-01","endDate":"2024-01-31", "airlines":["MU"]}
                """;
    }

    @Override
    public String description() {
        return """
                查询航司排名，给定日期范围和航司，查询航司航班量排名。
                """;
    }

    @Override
    public String parameters() {
        String parameters = ParametersSingletonManager.getParameters("AirlineRankAction", () -> {
            FunctionCall functionCall = new FunctionCall();
            functionCall.setType("object");
            functionCall.setRequired(Lists.newArrayList("startDate", "endDate", "fields"));
            AirlineRankProperties properties = new AirlineRankProperties();
            properties.setStartDate(new BasicTypeDefaultList("string", "开始日期，格式: yyyy-MM-dd，例如: '2019-01-01'"));
            properties.setEndDate(new BasicTypeDefaultList("string", "结束日期，格式: yyyy-MM-dd，例如: '2019-12-31'"));
            properties.setAirlines(new BasicTypeDefaultList("array", "航空公司IATA二字码数组，例如: ['9C']", new ItemsBean("string")));
            List<ResultScheme.ResultAttach> resultAttachList = result().getResultAttachList();
            List<String> fieldsList = resultAttachList.stream().map(ResultScheme.ResultAttach::getName).toList();
            // 修改 fields 部分，确保生成正确的字段列表
            properties.setFields(new BasicTypeDefaultList("array", "返回结果字段集合(根据需要多选), 各个字段含义解释如下: " + JsonUtil.marshalToString(resultAttachList)
                    + "。可选填字段如下: " + String.join(", ", fieldsList) + ",你需要尽量全面的选出适用字段。可以选多，不要选少。", new ItemsBean("string"), 1));
            functionCall.setProperties(properties);
            return functionCall.toString();
        });
        return parameters;
    }

    @Override
    public ParameterScheme defaultParameters() {
        Map<String, ParameterScheme.Property> properties = new HashMap<>();
        ParameterScheme.Property startDateProperty = new ParameterScheme.Property();
        startDateProperty.setType("string");
        startDateProperty.setDescription("开始日期，格式: yyyy-MM-dd，例如: '2019-01-01'");
        properties.put("startDate", startDateProperty);
        ParameterScheme.Property endDateProperty = new ParameterScheme.Property();
        endDateProperty.setType("string");
        endDateProperty.setDescription("结束日期，格式: yyyy-MM-dd，例如: '2019-12-31'");
        properties.put("endDate", endDateProperty);
        ParameterScheme.Property airlinesProperty = new ParameterScheme.Property();
        airlinesProperty.setType("array");
        airlinesProperty.setDescription("航空公司IATA三字码数组，例如: ['9C']");
        ParameterScheme.Property.Items airlinesItems = new ParameterScheme.Property.Items();
        airlinesItems.setType("string");
        airlinesProperty.setItems(airlinesItems);
        properties.put("airlines", airlinesProperty);
        List<ResultScheme.ResultAttach> resultAttachList = result().getResultAttachList();
        List<String> fieldsList = resultAttachList.stream().map(ResultScheme.ResultAttach::getName).collect(Collectors.toList());
        ParameterScheme.Property fieldsProperty = new ParameterScheme.Property();
        fieldsProperty.setType("array");
        fieldsProperty.setDescription("返回结果字段集合(根据需要多选), 字段含义: " + JsonUtil.marshalToString(resultAttachList)
                + "，可选字段: " + String.join(", ", fieldsList));
        fieldsProperty.setMinItems(1);
        ParameterScheme.Property.Items fieldsItems = new ParameterScheme.Property.Items();
        fieldsItems.setType("string");
        fieldsProperty.setItems(fieldsItems);
        properties.put("fields", fieldsProperty);
        ParameterScheme parameterScheme = new ParameterScheme("object", List.of("startDate", "endDate", "fields"), properties);
        return parameterScheme;
    }

    @Override
    public ResultScheme result() {
        ResultScheme resultScheme = new ResultScheme();
        List<ResultScheme.ResultAttach> resultAttachList = Lists.newArrayList();
        resultAttachList.add(new ResultScheme.ResultAttach("airline", "array", "航司IATA二字码"));
        resultAttachList.add(new ResultScheme.ResultAttach("isMajor", "boolean", "是否主要航司"));
        resultAttachList.add(new ResultScheme.ResultAttach("flightVolume", "integer", "航班量排名"));
        resultAttachList.add(new ResultScheme.ResultAttach("flightVolumeList", "array", "航班量排名列表"));
        resultAttachList.add(new ResultScheme.ResultAttach("passengerNum", "integer", "客运吞吐量排名"));
        resultAttachList.add(new ResultScheme.ResultAttach("passengerNumList", "array", "客运吞吐量排名列表"));
        resultAttachList.add(new ResultScheme.ResultAttach("cargoNum", "integer", "货运航班量排名"));
        resultAttachList.add(new ResultScheme.ResultAttach("cargoNumList", "array", "货运航班量排名列表"));
        resultScheme.setResultAttachList(resultAttachList);
        return resultScheme;
    }

    @Override
    public ActionResult run(String question, String input ,ExecuteOptions options) {
        try {
            AirlineRank req = JSON.parseObject(input, AirlineRank.class);
            boolean isLose = false;
            String startDate = req.getStartDate();
            String endDate = req.getEndDate();
            List<String> airlineList = req.getAirlines();
            StringBuilder qSb = new StringBuilder("缺少参数如下:");
            if (StringUtils.isEmpty(startDate)) {
                qSb.append("开始日期, ");
                isLose = true;
            }
            if (StringUtils.isEmpty(endDate)) {
                qSb.append("截止日期,");
                isLose = true;
            }
            if (isLose) {
                qSb.append("必填,请使用 conversation action 让用户补充这些参数");
                return new ActionResult(HttpStatus.BAD_REQUEST.value(), qSb.toString());
            }
            ResultScheme resultScheme = FlightScheduleActionUtils.resultScheme(req.getFields(), result());
            if (CollectionUtils.isNotEmpty(airlineList)) {
                return airlineResult(airlineList, startDate, endDate, input, resultScheme);
            }
            return new ActionResult( HttpStatus.BAD_REQUEST.value(), "暂不支持该条件查询");
        } catch (Throwable e) {
            log.error("error", e);
            return new ActionResult(HttpStatus.INTERNAL_SERVER_ERROR.value(), "解析发生错误，请思考后再调用？");
        }
    }

    private ActionResult airlineResult(List<String> airlineList, String startDate, String endDate, String input, ResultScheme resultScheme) throws Exception {
        List<AirlineRankResp> airlineRankRespList = Lists.newArrayList();
        StringBuilder data = new StringBuilder();
        for (String airline : airlineList) {
            data.append(airline).append("航司的查询结果是：");
            String resp = DbSearchActionUtils.queryAirlineRank(host, port, startDate, endDate, airline);
            JSONObject json = JSON.parseObject(resp);
            JSONObject respData = json.getJSONObject("data");
            if (null == respData) {
                continue;
            }
            AirlineRankResp airlineRankResp = JSON.parseObject(String.valueOf(respData), AirlineRankResp.class);
            airlineRankResp.setCargoNumList(airlineRankResp.getCargoNumList().subList(ConstantUtils.COMMON_INT_ZERO, ConstantUtils.COMMON_INT_TEN));
            airlineRankResp.setFlightVolumeList(airlineRankResp.getFlightVolumeList().subList(ConstantUtils.COMMON_INT_ZERO, ConstantUtils.COMMON_INT_TEN));
            airlineRankResp.setPassengerNumList(airlineRankResp.getPassengerNumList().subList(ConstantUtils.COMMON_INT_ZERO, ConstantUtils.COMMON_INT_TEN));
            airlineRankRespList.add(airlineRankResp);
        }
        log.info("airlineResult：{}", data);
        return AnswerUtils.answer(this.name(), input, airlineRankRespList, resultScheme);
    }
}